package top.jfunc.token.redis;

import org.springframework.data.redis.core.RedisTemplate;
import top.jfunc.token.ErrorCountManager;

import java.util.concurrent.TimeUnit;

/**
 * redis实现错误管理器
 * @author xiongshiyan at 2018/10/8 , contact me with email yanshixiong@126.com or phone 15208384257
 */
public abstract class AbstractRedisErrorCountManager<M> implements ErrorCountManager<M> {
    private int threshold = 3;
    private RedisTemplate<Object,Object> redisTemplate;

    @Override
    public int currentErrorCount(M member) {
        Integer currentErrorCount = (Integer) redisTemplate.opsForValue().get(key(member));
        return null == currentErrorCount ? 0 : currentErrorCount;
    }

    @Override
    public int incrErrorCount(M member) {
        String key = key(member);
        Integer currentErrorCount = (Integer) redisTemplate.opsForValue().get(key);
        int errorCount = null == currentErrorCount ? 1 : currentErrorCount + 1;
        redisTemplate.opsForValue().set(key, errorCount, 1800, TimeUnit.SECONDS);
        return errorCount;
    }

    @Override
    public boolean reachThreshold(int currentErrorCount) {
        return currentErrorCount >= threshold;
    }

    @Override
    public void clearErrorCount(M member) {
        redisTemplate.delete(key(member));
    }

    /**
     * 根据实体或者标识获取key
     * @param m 实体或者标识
     * @return 返回保存标识和token关系的key
     */
    abstract protected String key(M m);

    public int getThreshold() {
        return threshold;
    }

    public void setThreshold(int threshold) {
        this.threshold = threshold;
    }

    public RedisTemplate<Object, Object> getRedisTemplate() {
        return redisTemplate;
    }

    public void setRedisTemplate(RedisTemplate<Object, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }
}
